package com.zbangmall.util.convert;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.json.JSONObject;
import org.json.XML;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 类型转换处理类
 */
public class TypeConvert {

	/**
	 * object对象 转换成 Str字符串
	 */
	public static String toStr(Object obj, TypeEnum strTypeEnum) {
		switch (strTypeEnum) {
			case XML:
				if (obj instanceof Map) {
					Map<String, String> map = (Map<String, String>) obj;
					StringBuffer        sb  = new StringBuffer();
					sb.append("<xml>");
					for (Map.Entry<String, String> entry : map.entrySet()) {
						String value = "<![CDATA[" + entry.getValue() + "]]>";
						sb.append("<" + entry.getKey() + ">" + value + "</" + entry.getKey() + ">");
					}
					sb.append("</xml>");
					return sb.toString();
				} else if (obj instanceof String) {
					try {
						//jsonStr2xmlStr
						JSONObject json = new JSONObject(obj.toString());
						String     xml  = "<xml>" + XML.toString(json) + "</xml>";
						return xml;
					} catch (org.json.JSONException e) {
						e.printStackTrace();
					}

				} else {
					return toDoc(obj).asXML();
				}
			case JSON:
				if (obj instanceof String) {
					try {
						//xmlStr2jsonStr
						String     xml  = obj.toString();
						JSONObject json = XML.toJSONObject(xml.replace("<xml>", "").replace("</xml>", ""));
						return json.toString();

					} catch (org.json.JSONException e) {
						e.printStackTrace();
					}
				} else {
					return JSON.toJSONString(obj);
				}

			default:
				return "";
		}
	}

	//region ****************************** 转各种格式的字符串 ******************************

	/**
	 * Document对象 转换成 object对象
	 */
	public static <T> T toObj(Document document, Class<T> clazz) {
		Map<String, String> map = new HashMap<>();
		// 获取根节点
		Element root = document.getRootElement();
		try {
			List<Element> properties = root.elements();
			for (Element pro : properties) {
				String propName  = pro.getName();
				String propValue = pro.getText();
				map.put(propName, propValue);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		//处理map里的JSON字符串字段,防止解析错误
		Map<String, Object> objMap = new TreeMap<>();
		Set<String>         keys   = map.keySet();
		for (String key : keys) {
			String str = map.get(key);
			try {
				//如果是JSON字符串，则转换成对象，再添加到objMap中
				objMap.put(key, JSON.parse(str));
			} catch (JSONException e) {
				//如果不是JSON字符串，则直接添加到objMap中
				objMap.put(key, str);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return JSON.parseObject(JSON.toJSONString(map), clazz);
	}
	//endregion ****************************** 转各种格式的字符串 ******************************


	//region ****************************** 各种类型转pojo对象 ******************************

	/**
	 * str字符串 转换成 object对象
	 */
	public static <T> T toObj(Class<T> clazz, String str, TypeEnum strTypeEnum) {
		switch (strTypeEnum) {
			case JSON:
				return JSON.parseObject(str, clazz);
			case XML:
				Document document = null;
				try {
					document = DocumentHelper.parseText(str);
				} catch (DocumentException e) {
					throw new RuntimeException("获取Document异常" + str);
				} // 获取根节点
				return toObj(document, clazz);

			default:
				return null;

		}
	}

	/**
	 * Map对象. 转换成 Document对象
	 */
	public static Document toDoc(Map<String, Object> map) {
		Document doc = DocumentHelper.createDocument();
		try {
			Element     root = doc.addElement("xml");
			Set<String> keys = map.keySet();
			for (String key : keys) {
				Element ele = root.addElement(key);
				ele.addCDATA(map.get(key).toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return doc;
	}
	//endregion ****************************** 各种类型转pojo对象 ******************************


	//region ****************************** 各种类型转Document对象 ******************************

	/**
	 * object对象. 转换成 Document对象
	 */
	public static Document toDoc(Object obj) {
		Document document = DocumentHelper.createDocument();
		try {
			// 创建根节点元素
			Element root = document.addElement(obj.getClass().getSimpleName());
			// 获取实体类b的所有属性，返回Field数组
			Field[] field = obj.getClass().getDeclaredFields();
			// 遍历所有有属性
			for (int j = 0; j < field.length; j++) {
				// 获取属属性的名字
				String name = field[j].getName();
				// 去除串行化序列属性
				if (!"serialVersionUID".equals(name)) {
					// 将属性的首字符大写，方便构造get，set方法
					name = name.substring(0, 1).toUpperCase() + name.substring(1);
					Method m = obj.getClass().getMethod("get" + name);
					// 获取属性值
					String  propValue = (String) m.invoke(obj);
					Element propertie = root.addElement(name);
					propertie.setText(propValue);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return document;
	}

	public static Map<String, Object> toMap(String str, TypeEnum strTypeEnum) {
		Map<String, Object> map = new HashMap();
		switch (strTypeEnum) {
			case XML:
				try {
					// 将字符串转为XML
					Document doc = DocumentHelper.parseText(str);
					// 获取根节点
					Element rootElt = doc.getRootElement();
					// 获取根节点下所有节点
					List<Element> list = rootElt.elements();
					for (Element element : list) {
						// 节点的name为map的key，text为map的value
						map.put(element.getName(), element.getText());
					}
					return map;
				} catch (Exception e) {
					e.printStackTrace();
				}
			case JSON:
				return JSON.parseObject(str, Map.class);
			default:
				return map;
		}
	}
	//endregion ****************************** 各种类型转Document对象 ******************************


	public enum TypeEnum {
		XML, JSON
	}


}
